package cn.hg.solon.youcan.framework.directive.common;

import java.util.function.Supplier;

import org.dromara.hutool.core.text.StrValidator;
import org.dromara.hutool.core.util.ObjUtil;
import org.noear.solon.annotation.Inject;

import com.jfinal.template.Env;
import com.jfinal.template.TemplateException;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.Scope;

import cn.hg.solon.youcan.common.constant.CacheConstants;
import cn.hg.solon.youcan.framework.cache.YoucanCacheService;
import cn.hg.solon.youcan.framework.directive.BaseDirective;
import cn.hg.solon.youcan.system.entity.Config;
import cn.hg.solon.youcan.system.service.ConfigService;

/**
 * 系统参数指令基类
 * 
 * @author 胡高
 */
public abstract class BaseConfigDirective extends BaseDirective {

    @Inject
    private ConfigService configService;

    @Inject
    private YoucanCacheService cacheService;

    /**
     * 获取指令名称
     * 
     * @return 指令名称
     */
    public abstract String getDirectiveName();

    /**
     * 获取系统参数类型
     * 
     * @return 参数类型
     */
    public abstract String getType();

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.framework.directive.BaseDirective#onRender(com.jfinal.template.Env, com.jfinal.template.stat.Scope, com.jfinal.template.io.Writer)
     */
    @Override
    public void onRender(Env env, Scope scope, Writer writer) {
        // 参数代码
        String code = this.getParaToString(0, scope);
        if (StrValidator.isBlank(code)) {
            throw new TemplateException("The parameter of #" + this.getDirectiveName() + " directive can not be blank",
                this.location);
        }

        // 获取参数类型
        final String type = StrValidator.isBlank(this.getParaToString(1, scope)) ? this.getType() : this.getParaToString(1, scope);

        // 获取系统参数实例
        Config config = this.cacheService.getOrStoreTag(
            CacheConstants.SYS_CONFIG_KEY + ":" + type + ":" + code,
            CacheConstants.CACHE_SECONDS_ONE_DAY, new Supplier<Config>() {
                @Override
                public Config get() {
                    // 从服务中获取系统参数实例
                    return BaseConfigDirective.this.configService.getByTypeAndCode(type, code);
                }
            } , CacheConstants.SYS_CONFIG_TAG);

        try {
            // 输出系统参数值到页面
            if (ObjUtil.isNotNull(config)) {
                writer.write(config.getValue());
            }
        } catch (Exception e) {
            throw new TemplateException(e.getMessage(), this.location, e);
        }
    }

}
